package com.example.userlogindemo.controller;

import com.example.userlogindemo.assist.LoginForm;
import com.example.userlogindemo.assist.ProvideInfo;
import com.example.userlogindemo.entity.Userdata;
import com.example.userlogindemo.entity.HelpInfo;
import com.example.userlogindemo.repository.HelpInfoRepository;
import com.example.userlogindemo.repository.UserRepository;
import org.lionsoul.ip2region.xdb.Searcher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping("/")
public class HelpInfoController {

    @Autowired
    private HelpInfoRepository helpInfoRepository;
    @Autowired
    private UserRepository userRepository;

    /*
     * 发布求助信息
     * */
    @PostMapping("/addHelpInfo")
    public ResponseEntity<Void> HelpInfoUploader(@RequestBody HelpInfo helpInfo) {
        // 清除id的值,使用JPA的自动增长主键
        if (helpInfo.getId() != null) {
            helpInfo.setId(null);
        }
        // 根据username查找用户
        Optional<Userdata> userConfirm = userRepository.findById(helpInfo.getUsername());
        // 用户未找到
        if (userConfirm.isEmpty()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }
        // 上传信息到数据库
        helpInfoRepository.save(helpInfo);
        return ResponseEntity.status(HttpStatus.OK).build();
    }

    /*
     * 获取城市的求助列表
     * */
    @GetMapping("/getCityHelpListForUser/{cityName}")
    public ResponseEntity<List<HelpInfo>> getCityHelpInfo(@PathVariable String cityName) {
        List<HelpInfo> dataList = helpInfoRepository.findByCityAndState(cityName, 0);
        // 检查列表是否为空
        if (dataList.isEmpty()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }
        // 返回列表
        return ResponseEntity.status(HttpStatus.OK).body(dataList);
    }

    /*
     * 向他人提供帮助
     * 验证帮助者身份信息,然后根据传入id号查询helpInfo,修改其信息
     * */
    @PostMapping("/acceptHelpInfo")
    public ResponseEntity<Void> offerHelp(@RequestBody ProvideInfo provideInfo) {
        // 根据username查找用户
        Optional<Userdata> userConfirm = userRepository.findById(provideInfo.getResponseUsername());
        // 用户未找到
        if (userConfirm.isEmpty()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }
        // 根据id查询helpInfo
        Optional<HelpInfo> helpInfoConfirm = helpInfoRepository.findById(provideInfo.getId());
        if (helpInfoConfirm.isEmpty()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }
        // 修改helpInfo信息
        helpInfoConfirm.get().setResponseUsername(provideInfo.getResponseUsername());
        helpInfoConfirm.get().setState(1);
        // 更新数据库
        helpInfoRepository.save(helpInfoConfirm.get());
        return ResponseEntity.status(HttpStatus.OK).build();
    }

    /*
     * 完成求助
     * */
    @PostMapping("/finishHelpInfo")
    public ResponseEntity<Void> completeHelp(@RequestBody ProvideInfo provideInfo) {
        // 根据username查找用户
        Optional<Userdata> userConfirm = userRepository.findById(provideInfo.getResponseUsername());
        // 用户未找到
        if (userConfirm.isEmpty()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }
        // 根据id查询helpInfo
        Optional<HelpInfo> helpInfoConfirm = helpInfoRepository.findById(provideInfo.getId());
        if (helpInfoConfirm.isEmpty()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }
        // 修改helpInfo信息
        helpInfoConfirm.get().setResponseUsername(provideInfo.getResponseUsername());
        helpInfoConfirm.get().setState(2);
        // 更新数据库
        helpInfoRepository.save(helpInfoConfirm.get());
        return ResponseEntity.status(HttpStatus.OK).build();
    }

    /*
     * 获取username发出的所有求助请求
     * */
    @PostMapping("/getMyHelpList")
    public ResponseEntity<List<HelpInfo>> getMyHelpList(@RequestBody LoginForm loginForm) {
        // 根据username查找用户
        Optional<Userdata> userConfirm = userRepository.findById(loginForm.getUsername());
        // 用户未找到
        if (userConfirm.isEmpty()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }
        // 验证密码
        if (userConfirm.get().getPassword().equals(loginForm.getPassword()) == false) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }
        // 查询数据库
        List<HelpInfo> myHelpList = helpInfoRepository.findByUsername(userConfirm.get().getUsername());
        return ResponseEntity.status(HttpStatus.OK).body(myHelpList);
    }

    /*
     * 获取username提供的所有帮助
     * */
    @PostMapping("/getMyProvideList")
    public ResponseEntity<List<HelpInfo>> getMyProvideList(@RequestBody LoginForm loginForm) {
        // 根据username查找用户
        Optional<Userdata> userConfirm = userRepository.findById(loginForm.getUsername());
        // 用户未找到
        if (userConfirm.isEmpty()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }
        // 验证密码
        if (userConfirm.get().getPassword().equals(loginForm.getPassword()) == false) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }
        // 查询数据库
        List<HelpInfo> myHelpList = helpInfoRepository.findByResponseUsername(userConfirm.get().getUsername());
        return ResponseEntity.status(HttpStatus.OK).body(myHelpList);
    }

    /*
     * 取消为id的求助
     * */
    @PostMapping("/cancelMyHelp")
    public ResponseEntity<Void> cancelHelp(@RequestBody ProvideInfo provideInfo) {
        // 根据id查找求助
        Optional<HelpInfo> helpInfoConfirm = helpInfoRepository.findById(provideInfo.getId());
        // 未找到
        if (helpInfoConfirm.isEmpty()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }
        // 修改状态并更新数据库
        helpInfoConfirm.get().setState(4);
        helpInfoRepository.save(helpInfoConfirm.get());
        return ResponseEntity.status(HttpStatus.OK).build();
    }

    /*
     * 取消对id的求助的帮助
     * 修改state为0, responseUsername置空
     * */
    @PostMapping("/cancelMyProvide")
    public ResponseEntity<Void> cancelOffer(@RequestBody ProvideInfo provideInfo) {
        // 根据id查找求助
        Optional<HelpInfo> helpInfoConfirm = helpInfoRepository.findById(provideInfo.getId());
        // 未找到
        if (helpInfoConfirm.isEmpty()) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }
        // 修改状态并更新数据库
        helpInfoConfirm.get().setState(0);
        helpInfoConfirm.get().setResponseUsername(null);
        helpInfoRepository.save(helpInfoConfirm.get());
        return ResponseEntity.status(HttpStatus.OK).build();
    }

    /*
     * 查询并返回所有与type相关的求助
     * */
    @GetMapping("/select{typeString}")
    public ResponseEntity<List<HelpInfo>> selectHelp(@PathVariable String typeString) {
        // 字符串映射到类型定义值上
        int typeDefinition = switch (typeString) {
            case "EpidemicInfo" -> 0;
            case "NaturalDisasterInfo" -> 1;
            case "WomenInfo" -> 2;
            default -> -1;
        };
        // 确认typeDefinition合法
        if (typeDefinition == -1) {
            return ResponseEntity.status(HttpStatus.NOT_FOUND).build();
        }
        // 查询相关求助信息
        List<HelpInfo> relatedHelpList = helpInfoRepository.findByTypeAndState(typeDefinition, 0/* 正在进行的求助 */);
        return ResponseEntity.status(HttpStatus.OK).body(relatedHelpList);
    }

    /**
     * 查询
     * 返回一页helpInfo数据库中的信息
     * @param numbers 页上数据条数
     * @return 数据库第0页
     * */
    @GetMapping("/debugHelp/{numbers}")
    public Page<HelpInfo> helpData(@PathVariable("numbers") Integer numbers) {
        // 检查numbers是否合法, 从0开始
        if (numbers < 0) {
            return null;
        }
        // 返回数据库第0页, 该页上有numbers条数据
        Pageable pageable = PageRequest.of(0, numbers);
        return helpInfoRepository.findAll(pageable);
    }

    /**
     * 通过ip地址获取所属国家-离线方式
     * @param ip IP地址
     * @return  国家信息
     */
    @GetMapping("/ip2region/{ip}")
    public static String getCountryByIpOffline(@PathVariable("ip") String ip, @Value("/home/must78/mySpringBootJar/ip2region.xdb") String dbPath) throws Exception {
        // 1、从 dbPath 加载整个 xdb 到内存。
        byte[] cBuff;
        try {
            cBuff = Searcher.loadContentFromFile(dbPath);
        } catch (Exception e) {
            System.out.printf("[ip2region]failed to load content from `%s`: %s\n", dbPath, e);
            return null;
        }
        // 2、使用上述的 cBuff 创建一个完全基于内存的查询对象。
        Searcher searcher;
        try {
            searcher = Searcher.newWithBuffer(cBuff);
        } catch (Exception e) {
            System.out.printf("[ip2region]failed to create content cached searcher: %s\n", e);
            return null;
        }
        // 3、查询
        String region;
        try {
            long sTime = System.nanoTime();
            region = searcher.search(ip);
            long cost = TimeUnit.NANOSECONDS.toMicros((long) (System.nanoTime() - sTime));
            System.out.printf("{region: %s, ioCount: %d, took: %d μs}\n", region, searcher.getIOCount(), cost);
        } catch (Exception e) {
            System.out.printf("[ip2region]failed to search(%s): %s\n", ip, e);
            return null;
        }
        return region;
    }
}